import * as localForage from 'localforage';

export enum StorageModuleEnum {
  Theme = 'theme',
  Task = 'task',
  Customer = 'customer',
  Product = 'product',
  Event = 'event',
  ServicePrice = 'servicePrice',
  Common = 'common',
  Paas = 'paas',
  Archive = 'archive', // 归档工单列
  serviceProvider = 'serviceProvider', // 服务商
  ProjectManage = 'projectManage', // 项目管理
  TaskManage = 'taskManage', // 任务管理
}

export type StorageSetType =
  | Array<any>
  | ArrayBuffer
  | Blob
  | Float32Array
  | Float64Array
  | Int8Array
  | Int16Array
  | Int32Array
  | Number
  | Object
  | Uint8Array
  | Uint16Array
  | Uint32Array
  | Uint8ClampedArray
  | String;

/**
 * 使用缓存
 * @param projectName 项目名称
 * @param module 模块名称
 * @param prefixKey 存储前缀 区分存储一般使用userId
 * @returns
 */
export function useStorage(
  projectName: 'shb-pc-fe',
  storeName: StorageModuleEnum | string = 'base',
  prefixKey = ''
) {
  const localForageInstance = localForage.createInstance({
    name: projectName,
    storeName,
  });

  /**
   * @description 获取存储key
   */
  function getStorageKey(key: string): string {
    return prefixKey ? `${prefixKey}-${key}` : key;
  }

  async function getItem<T, K>(
    key: string,
    defaultValue: K
  ): Promise<T | K | null> {
    try {
      let storageKey = getStorageKey(key);
      // 如果 key 不存在，getItem() 将返回 null
      let value: T | K | null = await localForageInstance.getItem(storageKey);
      if (value !== null) return value;

      const storageValue = localStorage.getItem(storageKey);

      if (!storageValue) return defaultValue;
      try {
        return JSON.parse(storageValue);
      } catch (error) {
        return defaultValue ?? null;
      }
    } catch (error) {
      console.error('storageGet error', error);
      return defaultValue;
    }
  }

  /**
   * @description 设置存储
   *  注意此方法是异步执行的
   */
  async function setItem(key: string, value: StorageSetType): Promise<any> {
    if (!key)
      return console.warn(
        `Caused: can not set storage, because there is no key`
      );

    const storageKey = getStorageKey(key);
    // log.info('storageKey', storageKey)
    // log.info('storageSet data', value)

    try {
      return localForageInstance.setItem(storageKey, value);
    } catch (error) {
      localStorage.setItem(`${storeName}-${storageKey}`, JSON.stringify(value));
      console.error('storageSet error', error);
    }
  }

  /**
   * 删除一项
   * @param key key
   */
  async function removeItem<T, K>(key: string): Promise<any> {
    const storageKey = getStorageKey(key);

    try {
      return localForageInstance.removeItem(storageKey);
    } catch (error) {
      localStorage.removeItem(`${storeName}-${storageKey}`);
      console.error('storageRemoveItem error', error);
    }
  }

  /**
   * 清空所有存储
   * !谨慎使用此方法。
   * @param module
   */
  function clear() {
    localForageInstance.clear();
  }

  return {
    getItem,
    setItem,
    removeItem,
    clear,
  };
}
